﻿/**
 * @file main.c
 * @brief 覆冰监测器主程序
 * @version 2.2
 * @date 2023-05-20
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <time.h>
#include <unistd.h>
#include <sys/stat.h>  // 添加，用于mkdir函数
#include <sys/types.h>  // 添加，用于目录操作
#ifdef _WIN32
#include <direct.h>  // 添加，用于Windows平台的_mkdir函数
#endif

// 项目头文件
#include "common_defs.h"
#include "app_control.h"
#include "system_utils.h"
#include "thread_utils.h"
#include "visual_monitor.h"
#include "stereo_monitor.h"
#include "data_fusion.h"
#include "ice_calculation.h"
#include "simulation.h"
#include "uart_protocol.h"
#include "uart_handler.h"
#include "image_process.h"
// 新增头文件
#include "debug_images.h"
#include "camera_capture_mode.h"
#include "camera_capture_thread.h"
#include "hybrid_mode_thread.h"

// 定义新的运行模式
#define RUN_MODE_TRIPLE_CAMERA 10  // 从外部3个摄像头获取图像模式
#define RUN_MODE_HYBRID 7  // 混合模式

/**
 * @brief 主程序入口
 * 
 * @param argc 命令行参数数量
 * @param argv 命令行参数数组
 * @return int 程序执行结果
 */
int main(int argc, char *argv[]) {
    // 记录程序启动时间
    g_program_start_time = get_timestamp_ms();
    
    // 设置默认配置
    set_default_config();
    
    // 解析命令行参数
    if (parse_command_line(argc, argv) != 0) {
        print_usage(argv[0]);
        return 1;
    }
    
    // 如果是运行模式为0(退出)，则直接退出
    if (g_run_mode == RUN_MODE_EXIT) {
        printf("程序已退出\n");
        return 0;
    }
    
    // 如果是运行模式为6(帮助)，则显示帮助信息并退出
    if (g_run_mode == RUN_MODE_HELP) {
        print_usage(argv[0]);
        return 0;
    }
    
    // 检查运行模式是否有效
    if (g_run_mode != RUN_MODE_SIMULATION && g_run_mode != RUN_MODE_TRIPLE_CAMERA && g_run_mode != RUN_MODE_HYBRID) {
        printf("错误：只支持模式5(纯模拟模式)、模式10(三摄像头模式)和模式7(混合模式)\n");
        print_usage(argv[0]);
        return 1;
    }
    
    // 根据运行模式输出初始信息
    switch (g_run_mode) {
        case RUN_MODE_SIMULATION:
            printf("运行模式: 纯模拟模式，使用模拟传感器+400W摄像头进行等值线缆测量 (日志输出已精简)\n");
            break;
        case RUN_MODE_HYBRID:
            printf("运行模式: 混合模式，结合模拟数据和三摄像头功能，每10秒采集一次 (日志输出已精简)\n");
            break;
        case RUN_MODE_TRIPLE_CAMERA:
            printf("运行模式: 三摄像头模式，从外部3个摄像头获取图像\n");
            break;
        default:
            break;
    }
    
    // 设置信号处理器
    signal(SIGINT, signal_handler);
    signal(SIGTERM, signal_handler);

    // 初始化全局互斥锁系统
    if (init_global_mutex() != 0) {
        printf("初始化全局互斥锁系统失败\n");
        return 1;
    }
    
    // 初始化系统诊断模块，并启用看门狗
    if (init_diagnostics(true) != 0) {
        printf("初始化系统诊断模块失败\n");
        cleanup_global_mutex();
        return 1;
    }
    
    // 启动诊断线程
    if (start_diagnostics_thread() != 0) {
        printf("启动系统诊断线程失败\n");
        cleanup_diagnostics();
        cleanup_global_mutex();
        return 1;
    }

    // 初始化系统
    if (app_init_system() != 0) {
        log_message(LOG_LEVEL_ERROR, "系统初始化失败");
        cleanup_diagnostics();
        cleanup_global_mutex();
        return 1;
    }
    
    // 确保全局变量正确初始化 - 使用线程安全函数
    set_ice_thickness_safe(0.0f); // 初始无覆冰
    set_previous_ice_thickness_safe(0.0f); // 初始无覆冰的历史记录
    
    // 启动监测线程 - 只在三摄像头模式下启动
    if (g_run_mode == RUN_MODE_TRIPLE_CAMERA) {
        if (g_config.enable_visual) {
            if (start_visual_monitor_thread() != 0) {
                log_message(LOG_LEVEL_ERROR, "启动视觉监测线程失败");
                log_message(LOG_LEVEL_WARNING, "在三摄像头模式下继续运行，但400W摄像头可能无法正常工作");
            } else {
                log_message(LOG_LEVEL_INFO, "成功启动视觉监测线程，400W摄像头已初始化");
                log_message(LOG_LEVEL_INFO, "400W摄像头 URL: %s", g_config.visual_config.camera_url);
                log_message(LOG_LEVEL_INFO, "400W摄像头 分辨率: %dx%d", 
                          g_config.visual_config.width, g_config.visual_config.height);
            }
        }
        
        if (g_config.enable_stereo) {
            if (start_stereo_monitor_thread() != 0) {
                log_message(LOG_LEVEL_ERROR, "启动立体视觉线程失败");
            } else {
                log_message(LOG_LEVEL_INFO, "成功启动立体视觉线程，双800W摄像头已初始化");
            }
        }
    }
    
    // 设置运行标志
    g_running = true;
    
    // 主循环
    log_message(LOG_LEVEL_INFO, "系统已启动，进入主循环，采样间隔: %d ms", g_config.sampling_interval_ms);
    
    // 混合模式或三摄像头模式下，启动独立的线程
    if (g_run_mode == RUN_MODE_TRIPLE_CAMERA) {
        // 启动摄像头采集线程
        if (start_camera_capture_thread(g_camera_capture_count) != 0) {
            log_message(LOG_LEVEL_ERROR, "启动摄像头采集线程失败");
            cleanup_system();
            stop_diagnostics_thread();
            cleanup_diagnostics();
            cleanup_global_mutex();
            return 1;
        }
        
        log_message(LOG_LEVEL_INFO, "摄像头采集线程已启动，将在后台运行");
    } else if (g_run_mode == RUN_MODE_HYBRID) {
        // 启动混合模式线程
        if (start_hybrid_mode_thread() != 0) {
            log_message(LOG_LEVEL_ERROR, "启动混合模式线程失败");
            cleanup_system();
            stop_diagnostics_thread();
            cleanup_diagnostics();
            cleanup_global_mutex();
            return 1;
        }
        
        log_message(LOG_LEVEL_INFO, "混合模式线程已启动，将在后台运行");
    }
    
    // 主循环
    uint64_t last_sample_time = get_timestamp_ms();
    
    while (g_running) {
        // 当前时间
        uint64_t current_time = get_timestamp_ms();
        
        // 检查是否需要进行采样
        if (current_time - last_sample_time >= g_config.sampling_interval_ms) {
            // 更新最后采样时间
            last_sample_time = current_time;
            
            // 只在模拟模式下处理模拟数据
            if (g_run_mode == RUN_MODE_SIMULATION) {
                // 传感器数据包
                SensorDataPacket sensor_data_packet = {0};
                bool has_sensor_data = false;
                
                // 模拟模式下，始终使用模拟生成的传感器数据
                SensorData sensor_data = {0};
                get_simulation_sensor_data(&sensor_data);
                
                // 将SensorData转换为SensorDataPacket
                memcpy(&sensor_data_packet, &sensor_data, sizeof(SensorData));
                sensor_data_packet.timestamp = current_time;
                has_sensor_data = true;
                
                // 视觉覆冰数据
                VisualIceData visual_data = {0};
                bool has_visual_data = false;
                
                // 生成模拟视觉数据
                if (convert_simulation_visual_data(&visual_data, g_config.cable_params.diameter, current_time)) {
                    has_visual_data = true;
                }
                
                // 立体视觉数据
                StereoData stereo_data = {0};
                bool has_stereo_data = false;
                
                // 生成模拟立体视觉数据
                if (convert_simulation_stereo_data(&stereo_data, g_config.cable_params.diameter, current_time)) {
                    has_stereo_data = true;
                }
                
                // 进行数据融合
                if (has_sensor_data || has_visual_data || has_stereo_data) {
                    // 创建融合数据包
                    FusionData fusion_data = {0};
                    
                    // 确定哪些数据可用
                    int available_data = 0;
                    if (has_sensor_data) available_data |= SENSOR_DATA_AVAILABLE;
                    if (has_visual_data) available_data |= VISUAL_DATA_AVAILABLE;
                    if (has_stereo_data) available_data |= STEREO_DATA_AVAILABLE;
                    
                    // 使用数据融合模块处理所有数据
                    if (fuse_all_data(
                            has_sensor_data ? &sensor_data_packet : NULL,
                            has_visual_data ? &visual_data : NULL,
                            has_stereo_data ? &stereo_data : NULL,
                            available_data,
                            &g_config.cable_params,
                            g_run_mode,
                            &fusion_data)) 
                    {
                        // 获取当前覆冰厚度（线程安全）
                        float current_thickness = get_ice_thickness_safe();
                        
                        // 输出等值线缆测量结果
                        printf("\n[等值线缆测量-传感器+400W摄像头] "
                              "传感器厚度估计=%.2fmm, 视觉厚度=%.2fmm, 最终厚度=%.2fmm, "
                              "拉力1=%.1fN, 拉力2=%.1fN, "
                              "温度=%.1f℃, 湿度=%.1f%%, 风速=%.1fm/s, 风向=%.1f°\n",
                              has_sensor_data ? (fusion_data.sensor_tension - g_config.cable_params.tension_no_ice) / 10.0f : 0.0f,
                              fusion_data.visual_thickness,
                              fusion_data.ice_volume > 0 ? current_thickness : 0.0f,
                              has_sensor_data ? sensor_data_packet.tension1 : 0.0f,
                              has_sensor_data ? sensor_data_packet.tension2 : 0.0f,
                              fusion_data.temperature, fusion_data.humidity,
                              fusion_data.wind_speed, fusion_data.wind_direction);
                        
                        // 更新历史厚度（线程安全）
                        update_ice_thickness_safe(current_thickness);
                        
                        // 显示等值线缆参数
                        printf("[等值线缆参数] "
                              "覆冰厚度=%.2fmm, 冰重量=%.3fkg/m, 风险等级=%s\n",
                              current_thickness, 
                              fusion_data.ice_weight, 
                              risk_level_names[fusion_data.risk_level < 5 ? fusion_data.risk_level : 4]);
                        
                        // 输出真实线缆测量结果
                        printf("\n[真实线缆测量-双目视觉模式] "
                              "覆冰厚度=%.2fmm, 距离=%.2fm, 视差=%.1f, "
                              "温度=%.1f℃, 湿度=%.1f%%, 风速=%.1fm/s, 风向=%.1f°\n",
                              fusion_data.stereo_thickness,
                              stereo_data.distance, stereo_data.disparity,
                              fusion_data.temperature, fusion_data.humidity,
                              fusion_data.wind_speed, fusion_data.wind_direction);
                        
                        // 显示真实线缆参数
                        printf("[真实线缆参数] "
                              "覆冰厚度=%.2fmm, 冰体积=%.2fmm³/mm, 风险等级=%s\n",
                              fusion_data.stereo_thickness,
                              fusion_data.ice_volume,
                              risk_level_names[fusion_data.risk_level < 5 ? fusion_data.risk_level : 4]);
                        
                        // 保存融合数据
                        save_fusion_data(&fusion_data);
                    } else {
                        log_message(LOG_LEVEL_ERROR, "数据融合处理失败");
                    }
                } else {
                    log_message(LOG_LEVEL_WARNING, "没有可用的数据");
                }
            } else if (g_run_mode == RUN_MODE_TRIPLE_CAMERA) {
                // 在三摄像头模式下，检查采集线程状态
                CaptureThreadState state = get_camera_capture_thread_state();
                
                if (state == CAPTURE_THREAD_ERROR) {
                    log_message(LOG_LEVEL_ERROR, "摄像头采集线程出错，尝试重新启动");
                    
                    // 停止并重新启动摄像头采集线程
                    stop_camera_capture_thread();
                    if (start_camera_capture_thread(g_camera_capture_count) != 0) {
                        log_message(LOG_LEVEL_ERROR, "重新启动摄像头采集线程失败");
                    }
                } else if (state == CAPTURE_THREAD_STOPPED) {
                    // 线程已结束，根据需求可以重新启动或者结束程序
                    log_message(LOG_LEVEL_INFO, "摄像头采集线程已完成");
                    
                    // 如果需要自动重新启动，取消下面的注释
                    // if (start_camera_capture_thread(g_camera_capture_count) != 0) {
                    //     log_message(LOG_LEVEL_ERROR, "重新启动摄像头采集线程失败");
                    // }
                }
            } else if (g_run_mode == RUN_MODE_HYBRID) {
                // 在混合模式下，检查混合模式线程状态
                HybridThreadState state = get_hybrid_mode_thread_state();
                
                if (state == HYBRID_THREAD_ERROR) {
                    log_message(LOG_LEVEL_ERROR, "混合模式线程出错，尝试重新启动");
                    
                    // 停止并重新启动混合模式线程
                    stop_hybrid_mode_thread();
                    if (start_hybrid_mode_thread() != 0) {
                        log_message(LOG_LEVEL_ERROR, "重新启动混合模式线程失败");
                    }
                } else if (state == HYBRID_THREAD_STOPPED) {
                    // 线程已结束，根据需求可以重新启动或者结束程序
                    log_message(LOG_LEVEL_INFO, "混合模式线程已完成");
                    
                    // 如果需要自动重新启动，取消下面的注释
                    // if (start_hybrid_mode_thread() != 0) {
                    //     log_message(LOG_LEVEL_ERROR, "重新启动混合模式线程失败");
                    // }
                }
            }
        }
        
        // 短暂休眠，防止CPU占用过高
        thread_sleep(100);
        
        // 检查看门狗
        reset_watchdog();
    }
    
    // 如果摄像头采集线程在运行，停止它
    if (g_run_mode == RUN_MODE_TRIPLE_CAMERA) {
        stop_camera_capture_thread();
    } else if (g_run_mode == RUN_MODE_HYBRID) {
        stop_hybrid_mode_thread();
    }
    
    // 清理资源
    log_message(LOG_LEVEL_INFO, "系统正在关闭...");
    cleanup_system();
    stop_diagnostics_thread();
    cleanup_diagnostics();
    cleanup_global_mutex();
    
    printf("系统已安全关闭\n");
    return 0;
}


